classdef KabumWindow < handle
    %%KABUMGUI Dooku Synthesizer Kabum window GUI class
    properties
        % Figure variables
        hfig;
        handles;

        % Instrument data
        Data;
    end
    
    properties (SetObservable)
        finish;
    end
    
    methods
        
        function obj = KabumWindow
            % Figure Load
            obj.hfig = hgload('KabumGUI.fig');
            obj.handles = guihandles(obj.hfig);
            
            % Callbacks Definitions
            set(obj.handles.instrumentWindow, 'CloseRequestFcn', @(src, event) finishSelect(obj, src, event));
            set(obj.handles.attackEdit, 'Callback', @(src, event) attackChange(obj, src, event));
            set(obj.handles.attackSlider, 'Callback', @(src, event) attackSlider(obj, src, event));
            set(obj.handles.qEdit, 'Callback', @(src, event) QChange(obj, src, event));
            set(obj.handles.uniformRad, 'Callback', @(src, event) randomnessSelect(obj, src, event));
            set(obj.handles.gaussianRad, 'Callback', @(src, event) randomnessSelect(obj, src, event));
            set(obj.handles.freqEdit, 'Callback', @(src, event) freqChange(obj, src, event));
            bg_image = imread('play.png');
            set(obj.handles.play, 'Callback', @(src, event) play(obj, src, event), 'CData', bg_image);
            
            obj.defaultVariables();
        end
        
        function defaultVariables(obj)
            obj.Data.name = 'Kabum';
            obj.Data.attack = 1;
            obj.Data.Q = 50;
            obj.Data.randomness = 'uniform';
            obj.Data.testFreq = 220;
            obj.Data.instrument = [];
        end
        
        function visible(obj)
            set(obj.hfig, 'Visible', 'on');
            set(obj.hfig, 'Windowstyle', 'modal');
        end
        
        function refreshWindow(obj, dataIn)
            obj.Data = dataIn;
            set(obj.handles.attackEdit, 'String', num2str(obj.Data.attack));
            set(obj.handles.attackSlider, 'Value', obj.Data.attack);
            set(obj.handles.qEdit, 'String', num2str(obj.Data.Q));
            if strcmp(obj.Data.randomness, 'uniform')
                set(obj.handles.uniformRad, 'Value', 1);
                set(obj.handles.gaussianRad, 'Value', 0);
            else
                set(obj.handles.uniformRad, 'Value', 0);
                set(obj.handles.gaussianRad, 'Value', 1);
            end
            set(obj.handles.freqEdit, 'String', num2str(obj.Data.testFreq));
        end
        
        function instrumentData = saveData(obj)
            
        end
        
        function obj = attackChange(obj, ~, ~)
            attackAux = str2double(get(obj.handles.attackEdit, 'String'));
            if sum(isnan(attackAux)) || sum(attackAux < 0) ||  sum(attackAux > 1)
                errordlg('Attack coeficient must be a numeric value between 0 and 1.', 'Inconsistent error');
                set(obj.handles.attackEdit, 'String', obj.Data.attack);
            else
                obj.Data.attack = attackAux;
                set(obj.handles.attackSlider, 'Value', obj.Data.attack);
            end
        end
        
        function obj = attackSlider(obj, src, ~)
            obj.Data.attack = get(src, 'Value');
            set(obj.handles.attackEdit, 'String', obj.Data.attack);
        end
        
        function obj = QChange(obj, ~, ~)
            QAux = str2double(get(obj.handles.qEdit, 'String'));
            if sum(isnan(QAux)) || sum(QAux < 0)
                errordlg('Q must be a positive numeric value.', 'Inconsistent error');
                set(obj.handles.qEdit, 'String', obj.Data.Q);
            else
                obj.Data.Q = QAux;
            end
        end
        
        function obj = randomnessSelect(obj, src, ~)
            if src
                set(src, 'Value', 1);
            end
            if get(obj.handles.uniformRad, 'Value')
                obj.Data.randomness = 'uniform';
            else
                obj.Data.randomness = 'gaussian';
            end
        end
        
        function obj = freqChange(obj, ~, ~)
            freqAux = str2double(get(obj.handles.freqEdit, 'String'));
            if sum(isnan(freqAux)) || sum(freqAux < 0)
                errordlg('Test frequency must be a positive numeric value.', 'Inconsistent error');
                set(obj.handles.freqEdit, 'String', obj.Data.testFreq);
            else
                obj.Data.testFreq = freqAux;
            end
        end
        
        function obj = play(obj, ~, ~)
            Fs = 44100;
            y = Kabum(obj.Data.testFreq, 1, obj.Data, Fs);
            y = y / max(abs(y)) * 0.95;    
            sound(y, Fs);
        end        
        
        
        function obj = finishSelect(obj, ~, ~)
            obj.finish = 1;
            set(obj.hfig, 'Visible', 'off');
            set(obj.hfig, 'Windowstyle', 'normal');
        end
        
    end
    
end